Skip to content

第13章 LangChain向量数据库集成

学习目标

  • 理解LangChain向量存储抽象层的设计与工作原理
  • 掌握主流向量数据库与LangChain的集成方法
  • 学习如何构建基于向量数据库的知识检索系统
  • 了解向量检索的高级优化技术

LangChain中的向量存储抽象

LangChain提供了统一的向量存储抽象层,使开发者能够轻松地切换不同的向量数据库,而不需要修改上层应用逻辑。

参考课程视频中的内容

1. 向量存储的核心概念

在LangChain中,向量存储抽象包含以下核心概念:

  • Documents:要索引的文本文档,可以包含元数据
  • Embeddings:将文本转换为向量的模型
  • VectorStore:存储和检索向量的数据库
  • Retrievers:从向量存储中检索相关文档的接口

2. 向量存储的基本功能

LangChain的向量存储抽象提供了以下基本功能:

  1. 添加文档:将文档转换为向量并存储
  2. 相似性搜索:根据查询向量查找最相似的文档
  3. 过滤搜索:根据元数据过滤搜索结果
  4. 作为检索器:提供标准化的检索接口

集成主流向量数据库

LangChain支持多种向量数据库的集成,下面我们将介绍几种常用的向量数据库的使用方法。

1. Chroma

Chroma是一个轻量级的开源向量数据库,非常适合本地开发和小型应用。

python
from langchain.vectorstores import Chroma
from langchain.embeddings import DeepSeekEmbeddings
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter

# 初始化Embedding模型
embeddings = DeepSeekEmbeddings(api_key="your-api-key")

# 加载文档
loader = TextLoader("./data/documents.txt")
documents = loader.load()

# 文本分割
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)

# 创建Chroma向量存储
vectorstore = Chroma.from_documents(
    documents=docs,
    embedding=embeddings,
    persist_directory="./chroma_db"  # 持久化存储路径
)

# 相似性搜索
query = "人工智能的伦理问题"
results = vectorstore.similarity_search(query, k=3)
for doc in results:
    print(doc.page_content)
    print(doc.metadata)
    print("---")

# 持久化
vectorstore.persist()

# 加载已有的向量存储
loaded_vectorstore = Chroma(
    persist_directory="./chroma_db",
    embedding_function=embeddings
)

2. FAISS

FAISS是Facebook AI开发的高性能向量搜索库,支持大规模向量索引和高效检索。

python
from langchain.vectorstores import FAISS

# 创建FAISS向量存储
vectorstore = FAISS.from_documents(docs, embeddings)

# 相似性搜索
results = vectorstore.similarity_search_with_score(query, k=3)
for doc, score in results:
    print(f"Score: {score}")
    print(doc.page_content)
    print("---")

# 保存到磁盘
vectorstore.save_local("./faiss_index")

# 从磁盘加载
loaded_vectorstore = FAISS.load_local("./faiss_index", embeddings)

3. Pinecone

Pinecone是一个云托管的向量数据库服务,提供高性能和可扩展的向量搜索。

python
import os
from langchain.vectorstores import Pinecone
import pinecone

# 初始化Pinecone
pinecone.init(
    api_key=os.environ["PINECONE_API_KEY"],
    environment=os.environ["PINECONE_ENVIRONMENT"]
)

# 创建索引(如果不存在)
index_name = "langchain-demo"
if index_name not in pinecone.list_indexes():
    pinecone.create_index(
        name=index_name,
        dimension=1536,  # 根据embedding模型维度设置
        metric="cosine"
    )

# 创建Pinecone向量存储
vectorstore = Pinecone.from_documents(
    docs,
    embeddings,
    index_name=index_name
)

# 相似性搜索
results = vectorstore.similarity_search(
    query,
    k=3,
    filter={"category": "AI research"}  # 元数据过滤
)

4. Milvus

Milvus是一个开源的向量数据库,支持大规模向量搜索和存储。

python
from langchain.vectorstores import Milvus

# 连接Milvus服务
vectorstore = Milvus.from_documents(
    docs,
    embeddings,
    connection_args={
        "host": "localhost",
        "port": "19530"
    },
    collection_name="langchain_collection"
)

# 相似性搜索
results = vectorstore.similarity_search(query, k=3)

5. 集成DeepSeek Embeddings

LangChain可以轻松集成DeepSeek的embedding模型:

python
from langchain.embeddings import DeepSeekEmbeddings
from langchain.vectorstores import Chroma

# 初始化DeepSeek embeddings
embeddings = DeepSeekEmbeddings(api_key="your-api-key")

# 创建向量存储
vectorstore = Chroma.from_documents(docs, embeddings)

# 查询
query = "DeepSeek AI的特点和优势"
results = vectorstore.similarity_search(query, k=3)

构建知识检索系统

1. 基础检索问答系统

使用向量数据库构建简单的检索问答系统:

python
from langchain.chains import RetrievalQA
from langchain.llms import DeepSeek

# 初始化LLM
llm = DeepSeek(api_key="your-api-key")

# 创建检索器
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})

# 创建检索问答链
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",  # 直接将所有检索文档拼接作为上下文
    retriever=retriever,
    verbose=True
)

# 执行问答
question = "DeepSeek模型有哪些应用场景?"
answer = qa_chain.run(question)
print(answer)

2. 构建对话式检索问答系统

加入对话历史的检索问答系统:

python
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferMemory

# 初始化记忆组件
memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True
)

# 创建对话式检索问答链
qa_chain = ConversationalRetrievalChain.from_llm(
    llm=llm,
    retriever=retriever,
    memory=memory,
    verbose=True
)

# 第一轮对话
response = qa_chain({"question": "什么是大语言模型?"})
print(response["answer"])

# 第二轮对话(引用前文信息)
response = qa_chain({"question": "它们有哪些局限性?"})
print(response["answer"])

3. 支持元数据过滤的检索问答系统

实现基于元数据过滤的检索问答系统:

python
from langchain.chains import RetrievalQA
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainFilter

# 创建元数据过滤器
metadata_filter_prompt = """
你是一个文档过滤专家。你需要判断以下文档是否与查询"{query}"相关。
该文档具有以下元数据:
- 类别: {category}
- 日期: {date}
- 作者: {author}

文档内容:
{page_content}

这个文档是否与查询"{query}"相关?请只回答"是"或"否"。
"""

filter_prompt = PromptTemplate(
    input_variables=["query", "page_content", "category", "date", "author"],
    template=metadata_filter_prompt
)

llm_filter = LLMChainFilter.from_llm(
    llm=llm,
    prompt=filter_prompt
)

# 创建带过滤的检索器
base_retriever = vectorstore.as_retriever(search_kwargs={"k": 10})
compression_retriever = ContextualCompressionRetriever(
    base_compressor=llm_filter,
    base_retriever=base_retriever
)

# 创建检索问答链
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=compression_retriever,
    verbose=True
)

# 执行问答
answer = qa_chain.run("DeepSeek在金融领域的应用")
print(answer)

向量检索的高级优化

1. 混合检索策略

结合关键词和向量检索的混合检索策略:

python
from langchain.retrievers import BM25Retriever, EnsembleRetriever

# 创建BM25检索器(基于关键词)
bm25_retriever = BM25Retriever.from_documents(docs)
bm25_retriever.k = 5  # 返回5个文档

# 创建向量检索器
vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 5})

# 创建混合检索器
ensemble_retriever = EnsembleRetriever(
    retrievers=[bm25_retriever, vector_retriever],
    weights=[0.3, 0.7]  # 权重分配
)

# 使用混合检索
results = ensemble_retriever.get_relevant_documents(query)

2. 自查询检索

使用LLM动态生成检索查询和过滤条件:

python
from langchain.retrievers import SelfQueryRetriever
from langchain.chains.query_constructor.base import AttributeInfo

# 定义可查询的元数据字段
metadata_field_info = [
    AttributeInfo(
        name="category",
        description="文档的类别,如'AI研究'、'产品介绍'等",
        type="string"
    ),
    AttributeInfo(
        name="date",
        description="文档的发布日期,格式为YYYY-MM-DD",
        type="date"
    ),
    AttributeInfo(
        name="author",
        description="文档的作者姓名",
        type="string"
    )
]

# 创建自查询检索器
document_content_description = "关于AI和大语言模型的文档"
retriever = SelfQueryRetriever.from_llm(
    llm=llm,
    vectorstore=vectorstore,
    document_contents=document_content_description,
    metadata_field_info=metadata_field_info,
    verbose=True
)

# 使用自然语言查询(包含过滤条件)
results = retriever.get_relevant_documents(
    "查找2023年1月后发布的关于DeepSeek金融应用的文档"
)

3. 层次化检索

实现层次化检索策略,提高大规模文档检索的效率:

python
from langchain.retrievers import ParentDocumentRetriever
from langchain.storage import InMemoryStore
from langchain.text_splitter import RecursiveCharacterTextSplitter

# 创建文档拆分器
parent_splitter = RecursiveCharacterTextSplitter(chunk_size=2000, chunk_overlap=200)
child_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)

# 创建文档存储
docstore = InMemoryStore()

# 创建层次化检索器
retriever = ParentDocumentRetriever(
    vectorstore=vectorstore,
    docstore=docstore,
    parent_splitter=parent_splitter,
    child_splitter=child_splitter
)

# 添加文档
retriever.add_documents(documents)

# 检索
results = retriever.get_relevant_documents(query)

4. 多查询检索

利用LLM生成多个查询变体提高检索效果:

python
from langchain.retrievers.multi_query import MultiQueryRetriever

# 创建多查询检索器
retriever = MultiQueryRetriever.from_llm(
    retriever=vectorstore.as_retriever(),
    llm=llm
)

# 使用多查询检索
queries = "DeepSeek模型如何用于自然语言处理?"
results = retriever.get_relevant_documents(queries)

5. RAG融合检索与生成

实现检索增强生成(RAG)系统,结合检索与生成能力:

python
from langchain.chains import RetrievalQA, LLMChain
from langchain.prompts import PromptTemplate

# 创建RAG提示模板
rag_prompt_template = """
请基于以下检索到的上下文信息,回答用户的问题。如果检索的信息不足以回答问题,请清楚地说明,不要编造信息。

上下文:
{context}

用户问题: {question}

详细回答:
"""
rag_prompt = PromptTemplate(
    template=rag_prompt_template,
    input_variables=["context", "question"]
)

# 创建检索QA链
qa = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=retriever,
    chain_type_kwargs={"prompt": rag_prompt},
    return_source_documents=True
)

# 执行RAG
result = qa({"query": "DeepSeek如何处理多语言任务?"})
print(result["result"])
print("\n来源文档:")
for doc in result["source_documents"]:
    print(f"- {doc.metadata.get('source', 'unknown')}")

思考题

  1. 对比不同向量数据库的性能和特性,你会在什么情况下选择Chroma、FAISS、Pinecone或Milvus?
  2. 如何评估向量检索系统的效果?有哪些指标可以用来衡量检索的准确性和相关性?
  3. 在处理大规模文档集时,如何优化向量检索的性能和资源消耗?
  4. 设计一个混合检索策略,结合向量检索、关键词检索和元数据过滤,如何实现这个系统?

接下来,我们将探讨如何将LangChain与搜索和向量数据库结合,构建完整的RAG应用。